
<script lang="ts">
import { ref } from "vue";

const CHUNK_SIZE = 1024 * 1024; // 每块 1MB

export default {
  setup() {
    const file = ref<File | null>(null);
    const progress = ref(0);

    // 处理文件选择
    const handleFileChange = (event: Event) => {
      const target = event.target as HTMLInputElement;
      if (target.files && target.files[0]) {
        file.value = target.files[0];
      }
    };

    // 上传文件
    const uploadFile = async () => {
      if (!file.value) return;

      const totalChunks = Math.ceil(file.value.size / CHUNK_SIZE);
      const fileHash = await calculateFileHash(file.value);

      for (let i = 0; i < totalChunks; i++) {
        const chunk = file.value.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE);
        const formData = new FormData();
        formData.append("file", chunk);
        formData.append("chunkIndex", i.toString());
        formData.append("totalChunks", totalChunks.toString());
        formData.append("fileHash", fileHash);

        await uploadChunk(formData);
        progress.value = ((i + 1) / totalChunks) * 100;
        console.log(`Chunk ${i + 1}/${totalChunks} uploaded`);
      }

      console.log("All chunks uploaded");
    };

    // 上传分片
    const uploadChunk = async (formData: FormData) => {
      return fetch("/upload", {
        method: "POST",
        body: formData,
      });
    };

    // 计算文件哈希值
    const calculateFileHash = async (file: File) => {
      const buffer = await file.arrayBuffer();
      const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
      return Array.from(new Uint8Array(hashBuffer))
        .map((b) => b.toString(16).padStart(2, "0"))
        .join("");
    };

    return {
      file,
      progress,
      handleFileChange,
      uploadFile,
    };
  },
};
</script>
<template>
    <div>
      <input type="file" @change="handleFileChange" />
      <button @click="uploadFile" :disabled="!file">上传</button>
      <div>上传进度: {{ progress }}%</div>
    </div>
  </template>
  